package boardInfo

import (
	"context"
	"fmt"
	"net"
	"r_log"
	"sync"
)

const (
	listerPort = 25411
)

var (
	gsf  *SmallFileServer
	once sync.Once
)

type SmallFileServer struct {
	ctx      context.Context
	cancel   context.CancelFunc
	listener net.Listener

	connLock sync.Mutex
	index    int
	mpConn   map[int]*stConnect
}

// 获取单例对象
func GetSmallServer() *SmallFileServer {

	if gsf == nil {
		once.Do(func() {
			gsf = &SmallFileServer{}
			gsf.mpConn = make(map[int]*stConnect)
		})
	}

	return gsf
}

// 开始服务
func (sf *SmallFileServer) StartServer() {
	sf.ctx, sf.cancel = context.WithCancel(context.TODO())
	go sf.startLister()
}

// 停止服务
func (sf *SmallFileServer) StopServer() {
	_ = sf.listener.Close()
	sf.cancel()
}

// 将网络连接保存到队列中
func (sf *SmallFileServer) addConnect(conn *stConnect) {
	sf.connLock.Lock()
	defer sf.connLock.Unlock()

	conn.index = sf.index
	sf.mpConn[sf.index] = conn
	sf.index++
}

// 将网络连接从队列中移除
func (sf *SmallFileServer) removeConnect(conn *stConnect) {
	sf.connLock.Lock()
	defer sf.connLock.Unlock()
	conn.closeConnect()
	_ = conn.conn.Close()
	delete(sf.mpConn, conn.index)
}

// 开始监听服务
func (sf *SmallFileServer) startLister() {
	sf.listener, _ = net.Listen("tcp", fmt.Sprintf(":%v", listerPort))
	for {
		c, err := sf.listener.Accept()
		if err != nil {
			_ = r_log.Logger.Error("SmallFileServer.StartServer Accept error:", err)
			continue
		}

		conn := getConnect(c)
		sf.addConnect(conn)

		//开始接收数据包
		go conn.receivePacket()
		//开始检测时间，发送定时消息
		go conn.startTickTask()
		//将消息发送给服务器
		go conn.writePacket()
	}
}
